package it.uniroma3.dia.ia.textcategorization.benchmark;

import it.uniroma3.dia.ia.textcategorization.model.Category;

import java.util.HashMap;
import java.util.Map;

/**
 * 
 * This class represents statistics referring to a
 * benchmark execution for a categorizer.
 * 
 * @author Marco Liceti.
 *
 */
public final class Report {

	private final Map<Category, Double> precision;
	private final Map<Category, Double> recall;

	Report(Map<Category, Double> precision, Map<Category, Double> recall) {
		this.precision = new HashMap<Category, Double>(precision);
		this.recall = new HashMap<Category, Double>(recall);
	}

	/**
	 * 
	 * Returns Precision for the given category.
	 * 
	 * @param category A Category instance.
	 * @return precision value
	 * 
	 */
	public Double getPrecisionFor(Category category) {
		return this.precision.get(category);
	}

	/**
	 * 
	 * Returns Recall for the given category.
	 * 
	 * @param category A Category instance.
	 * @return recall value
	 * 
	 */
	public Double getRecallFor(Category category) {
		return this.recall.get(category);
	}

	/**
	 * 
	 * Returns F1 Measure for the given category.
	 * 
	 * @param category A Category instance.
	 * @return F1 Measure value
	 * 
	 */
	public Double getF1MeasureFor(Category category) {
		Double precision = this.precision.get(category);
		Double recall = this.recall.get(category);
		return 2 * precision * recall / (precision + recall);
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("* Precision statistics for each category:");
		sb.append("\n");
		for (Category category : this.precision.keySet()) {
			if (this.precision.get(category) != null) {
				sb.append("* " + category.toString() + ": "
						+ this.getPrecisionFor(category) + ".");
				sb.append("\n");
			}
		}
		sb.append("\n");
		sb.append("* Recall statistics for each category:");
		sb.append("\n");
		for (Category category : this.recall.keySet()) {
			if (this.recall.get(category) != null) {
				sb.append("* " + category.toString() + ": "
						+ this.getRecallFor(category) + ".");
				sb.append("\n");
			}
		}
		sb.append("\n");
		sb.append("* F1 Measure statistics for each category:");
		sb.append("\n");
		for (Category category : this.precision.keySet()) {
			if (this.recall.containsKey(category)) {
				if (this.precision.get(category) != null
						&& this.recall.get(category) != null) {
					sb.append("* " + category.toString() + ": "
							+ this.getF1MeasureFor(category) + ".");
					sb.append("\n");
				}
			}
		}
		sb.append("\n");
		return sb.toString();
	}

}
